package io.lvdaxian.mybatis11.executor;

import io.lvdaxian.mybatis11.executor.statement.StatementHandler;
import io.lvdaxian.mybatis11.mapping.BoundSql;
import io.lvdaxian.mybatis11.mapping.MappedStatement;
import io.lvdaxian.mybatis11.session.Configuration;
import io.lvdaxian.mybatis11.session.ResultHandler;
import io.lvdaxian.mybatis11.session.RowBounds;
import io.lvdaxian.mybatis11.transaction.Transaction;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;

/**
 * 这里实现了 基础的执行器
 *
 * @author lihh
 */
public class SimpleExecutor extends BaseExecutor {
  
  public SimpleExecutor(Configuration configuration, Transaction transaction) {
    super(configuration, transaction);
  }
  
  @Override
  protected <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
    Configuration configuration = ms.getConfiguration();
    Statement stmt = null;
    
    // 新建一个 StatementHandler
    StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, rowBounds, resultHandler, boundSql);
    try {
      // 准备语句
      stmt = prepareStatement(handler);
      return handler.query(stmt, resultHandler);
    } catch (SQLException e) {
      throw new RuntimeException(e);
    } finally {
      closeStatement(stmt);
    }
  }
  
  private Statement prepareStatement(StatementHandler handler) throws SQLException {
    Statement stmt;
    Connection connection = transaction.getConnection();
    // 准备语句
    stmt = handler.prepare(connection);
    handler.parameterize(stmt);
    return stmt;
  }
  
  @Override
  protected int doUpdate(MappedStatement ms, Object parameter) throws SQLException {
    Statement stmt = null;
    try {
      Configuration configuration = ms.getConfiguration();
      // 新建一个 StatementHandler
      StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, RowBounds.DEFAULT, null, null);
      // 准备语句
      stmt = prepareStatement(handler);
      // StatementHandler.update
      return handler.update(stmt);
    } finally {
      closeStatement(stmt);
    }
  }
}
